package com.codeoss.framework.view.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.codeoss.framework.context.YunContext;
import com.codeoss.framework.data.metadata.Column;
import com.codeoss.framework.data.metadata.ColumnValidationRule;
import com.codeoss.framework.data.metadata.Table;
import com.codeoss.framework.data.metadata.TableValidationRule;
import com.codeoss.framework.expression.Expression;
import com.codeoss.framework.expression.IScriptServiceStore;
import com.codeoss.framework.util.StringUtils;
import com.codeoss.framework.view.service.IVariableService;

@Component
public class ValidatorUtil {
	@Autowired
	private IScriptServiceStore scriptServiceStore;
	
	@Autowired
	private IVariableService variableService;
	
	public void validate(YunContext yunContext, Table table, Map<String, Object> dataMap) {
		validateRequired(yunContext,table,dataMap);
		validateColumnList(yunContext,table,dataMap);
		validateTable(yunContext,table,dataMap);
	}
	
	public void validateRequired(YunContext yunContext, Table table, Map<String, Object> dataMap) {
		Iterator<Map.Entry<String,Object>> it=dataMap.entrySet().iterator();
		while(it.hasNext()) {
			Map.Entry<String,Object> entry=it.next();
			String key=entry.getKey();
			Object value=entry.getValue();
			Column column=table.getColumnByColumnName(key);
			if(!column.isPrimaryKey() && !column.isNullable()) {
				if(column.getDataType().equals("string") && StringUtils.isEmpty((String)value) ||value==null) {
					throw new RuntimeException(column.getName()+"不能为空");
				}
			}
			variableService.setVariableValue(yunContext, table.getTableName()+"_"+key, value);
		}
		it=dataMap.entrySet().iterator();
		while(it.hasNext()) {
			Map.Entry<String,Object> entry=it.next();
			String key=entry.getKey();
			Object value=entry.getValue();
			Column column=table.getColumnByColumnName(key);
			if(!column.isPrimaryKey() && (column.getDataType().equals("string") && StringUtils.isEmpty((String)value) ||value==null)) {
				String requiredExpression=column.getRequiredExpression();
				if(!StringUtils.isEmpty(requiredExpression)) {
					requiredExpression=requiredExpression.replace("@","");
					Expression expression=new Expression();
					expression.setScript(requiredExpression);
					expression.setScriptType(Expression.EXPRESSION_TYPE_JAVASCRIPT);
					boolean required=(boolean)scriptServiceStore.getScriptService(expression).eval(expression.getScript(), yunContext.getVarValueMap());
					if((required)) {
						throw new RuntimeException(column.getName()+"不能为空");
					}
				}
			}
		}
	}
	
	public void validateColumnList(YunContext yunContext, Table table, Map<String, Object> dataMap) {
		Iterator<Map.Entry<String,Object>> it=dataMap.entrySet().iterator();
		while(it.hasNext()) {
			Map.Entry<String,Object> entry=it.next();
			String key=entry.getKey();
			Column column=table.getColumnByColumnName(key);
			List<ColumnValidationRule> columnValidationRuleList=column.getColumnValidationRuleList();
			if(columnValidationRuleList!=null) {
				Object value=entry.getValue();
				Map<String,Object> binding=new HashMap<String,Object>();
				binding.put("value", value);
				for(int i=0;i<columnValidationRuleList.size();i++) {
					ColumnValidationRule columnValidationRule=columnValidationRuleList.get(i);
					com.codeoss.framework.expression.Expression validationRuleExpression=columnValidationRule.getValidationRuleExpression();
					boolean result=(boolean)scriptServiceStore.getScriptService(validationRuleExpression).eval(validationRuleExpression.getScript(), binding);
					if(result) {
						throw new RuntimeException(columnValidationRule.getValidationErrorMessage());
					}
				}
			}
		}
	}
	
	public void validateTable(YunContext yunContext,Table table, Map<String, Object> dataMap) {
		List<TableValidationRule> tableValidationRuleList=table.getTableValidationRuleList();
		if(tableValidationRuleList!=null) {
			for(int i=0;i<tableValidationRuleList.size();i++) {
				TableValidationRule tableValidationRule=tableValidationRuleList.get(i);
				com.codeoss.framework.expression.Expression validationRuleExpression=tableValidationRule.getValidationRuleExpression();
				boolean result=(boolean)scriptServiceStore.getScriptService(validationRuleExpression).eval(validationRuleExpression.getScript(), dataMap);
				if(result) {
					throw new RuntimeException(tableValidationRule.getValidationErrorMessage());
				}
			}
		}
	}
}
